home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX500 / DSMARK.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  12.6 KB  |  392 lines

  1. /*
  2.  *  Dsmark.c
  3.  *    Routines for performing a destructive markbad.
  4.  */
  5.  
  6. /* 23-Nov-87    ml.    just started.    
  7.  * 11-Nov-88    jye. change and add codes so that can be used for MS-DOS.
  8.  * 08-Aug-89    jye. change the max size of buffer for memory check.
  9.  */
  10.  
  11. #include "obdefs.h"
  12. #include "gemdefs.h"
  13. #include "osbind.h"
  14. #include "mydefs.h"
  15. #include "part.h"
  16. #include "bsl.h"
  17. #include "hdx.h"
  18. #include "addr.h"
  19.  
  20. extern SECTOR badbuf[];        /* bad sectors buffer */
  21.  
  22. extern int wdesk, hdesk;
  23. extern long nument();
  24. long sysize;                /* system memory size */
  25.  
  26. /*
  27.  *  Destructive Markbad for entire device.
  28.  *    Mechanism:
  29.  *        - write data to entire device, read it back, and compare
  30.  *          if there is any difference. (done in markdev())
  31.  *        - all new bad sectors are added to the bad sector list.
  32.  *          (done in markdev())
  33.  *        - repeat above for the number of passes passed in.
  34.  *    Input:
  35.  *        pdev - physical device number.
  36.  *        hdsiz - size of hard disk in sectors.
  37.  *        pass - number of passes to be performed.
  38.  *        pattern - data pattern to test the disk with.
  39.  *    Output:
  40.  *        bsl - bad sector list with added entries if any. (in bsl.h)
  41.  *    Return:
  42.  *        totbad - total number of bad sectors found.
  43.  *        ERROR - if any of the first 3 sectors is bad, or not enough
  44.  *            memory for buffer.
  45.  */
  46.  
  47. long
  48. dsmarkbad(pdev, hdsiz, pass, pattern)
  49. int pdev;    /* phys dev num */
  50. long hdsiz;    /* hard disk size */
  51. int pass;    /* num cycles */
  52. long pattern;    /* data pattern to test disk */
  53. {
  54.     char *inbuf;      /* buffer to hold data to be written to the disk */
  55.     char numbuf[10];
  56.     long totbad;      /* total num of bad sectors found */
  57.     long ret;          /* return code from markdev() */
  58.     long markdev();
  59.  
  60.     
  61.     /* Allocate memory for biggest data buffer necessary */
  62.     if ((sysize = Malloc(-1L)) <= 0)    {
  63.         return err(nomemory);
  64.     }
  65.     if ((sysize/512L) > MAXBUFSECT)     /*the max # of sector for hread() is 254*/ 
  66.         sysize = MAXBUFSECT * 512;     /*convert to bytes */
  67.  
  68.     if ((inbuf = (char *)Malloc(sysize)) <= 0)
  69.         return err(nomemory);
  70.  
  71.     /* Throw up message box to inform user about 
  72.        the processing of destructive markbad.  */
  73.     totbad = nument(VENDOR);  /* Number of existing VENDOR bad sectors */
  74.     ltoa(totbad, numbuf);
  75.     (dmrkmsg[OLDBAD].ob_spec)->te_ptext = numbuf;
  76.     strcpy((dmrkmsg[NEWBAD].ob_spec)->te_ptext, "0");  /* 0 new bad sector */
  77.     dmrkmsg[DMRKBAR].ob_width = 0;            /* haven't started yet */
  78.     dsplymsg(dmrkmsg);
  79.          
  80.     totbad = 0;    /* no NEW bad sectors yet */        
  81.     /* Loop for given number of passes */
  82.     while (pass) {
  83.         if ((ret = markdev(pdev, hdsiz, inbuf, pattern)) < 0) {
  84.             ret == ERROR;
  85.     } else {
  86.         totbad += ret;
  87.     }
  88.         pass--;
  89.     }
  90. wrapup:
  91.     erasemsg();
  92.     Mfree((long)inbuf);
  93.     if (ret < 0)
  94.         return (ret);
  95.     return(totbad);
  96. }
  97.  
  98.  
  99. /*
  100.  *  Fill up a character buffer with the given pattern.
  101.  *    Input:
  102.  *        buf - buffer to be filled.
  103.  *        size - size of buffer in bytes.
  104.  *        pattern - a 1-byte data to fill the buffer.
  105.  *    Output:
  106.  *        buf - buffer filled with the given pattern.
  107.  */
  108. fillbuf(buf, size, pattern)
  109. char *buf;
  110. long size;
  111. long pattern;
  112. {
  113.     long i;    /* index */
  114.     
  115.     for (i = 0; i < size; i += 4)
  116.     *(long *)&buf[i] = pattern;
  117. }
  118.  
  119.  
  120. /*
  121.  *  Markdev - Find bad sectors on a hard disk and record them in the Bad
  122.  *          Sector List.
  123.  *    Mechanism:
  124.  *        - write some given data to the entire device cylinder by
  125.  *          cylinder.
  126.  *        - read from the device cylinder by cylinder but in reverse
  127.  *          order.
  128.  *        - as data are read from the device, compare the written data
  129.  *          with the data read.  
  130.  *        - if there is any write, read or data error in a sector, that
  131.  *          sector will be considered bad.  (data error means data read
  132.  *          is different from data written.)
  133.  *        - add the bad sectors to the bad sector list.
  134.  *    Input:
  135.  *        pdev - physical device number.
  136.  *        hdsiz - size of hard disk in sectors.
  137.  *        databuf - buffer with the testing data.
  138.  *        pattern - data pattern to test with.
  139.  *    Output:
  140.  *        bsl - an updated bad sector list (ie. with newly found bad
  141.  *              sectors added to it).
  142.  *    Return:
  143.  *        totbad - total number of bad sectors found.
  144.  *        ERROR - Any of first 3 sectors on disk is bad.
  145.  */
  146. long
  147. markdev(pdev, hdsiz, databuf, pattern)
  148. int pdev;    /* phys dev number */
  149. long hdsiz;    /* size of hard disk in sectors */
  150. char *databuf;    /* testing data */ 
  151. long pattern;    /* data pattern */
  152. {
  153.     long sectcnt, cnt;        /* number of sectors to read */
  154.     long sect2mark;        /* number of sectors to mark */
  155.     SECTOR start, where;    /* where to start writing or reading */
  156.     long totbad;        /* total bad sectors found */
  157.     int nbad;            /* num bad sectors so far */
  158.     int ret=0;            /* return code from routines */
  159.     int clean;            /* indicate if chunk has any bad sector */
  160.     char numbuf[10];        /* buf to hold string converted from a number */
  161.  
  162.     
  163.     /*------------------------------------------------------------*/
  164.     /*  Write lots of sectors (MAXSECTS worth) at a time.      */
  165.     /*  If write error, loop through sectors within that cylinder */
  166.     /*  to find out exactly which sector(s) is bad, and add it to */
  167.     /*  the bad sector list if it's not already there.          */
  168.     /*------------------------------------------------------------*/
  169.  
  170.     sect2mark = hdsiz;        /* mark entire disk */
  171.     totbad = 0L;        /* no bad sectors yet */
  172.     nbad = 0;            /* no bad sectors found yet */
  173.     
  174.     start = 0L;
  175.     /* conver the bytes to the sectors */
  176.     sysize /= 512;
  177.     while (sect2mark != 0) {
  178.         if (sect2mark > sysize)
  179.             sectcnt = sysize;
  180.         else
  181.             sectcnt = sect2mark;
  182.             
  183.         /* fill buffer with given pattern */
  184.         fillbuf(databuf, (sectcnt << 9), pattern);
  185.             
  186.         if ((ret = wrsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  187.             if (tsterr(ret) == OK) {
  188.                 ret = ERROR;
  189.                 goto badnews;
  190.             }
  191.             cnt = sectcnt;
  192.             where = start;
  193.             while (cnt) {
  194.                 if ((ret = wrsects(pdev, 1, databuf, where)) != 0) {
  195.             if (tsterr(ret) == OK) {
  196.             ret = ERROR;
  197.             goto badnews;
  198.             }
  199.                   if (where < 3) {
  200.                       ret = err(rsrvbad);
  201.                       goto badnews;
  202.                   }
  203.                     
  204.                      badbuf[nbad++] = where;    /* store bad sector num */
  205.                     
  206.                     /* buffer is filled up, have to add bad sectors
  207.                        found so far to the BSL before continuing.   */
  208.                     if (nbad == WARNBADSECTS) {
  209.                         if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  210.                             ret = ERROR;
  211.                             goto badnews;
  212.                         }
  213.                         totbad += ret;    /* increment num bad sectors existing */
  214.                         prnbad(totbad);
  215.                         nbad = 0;    /* start counting again */
  216.                     }
  217.                 }
  218.                 where++;
  219.                 cnt--;
  220.             }
  221.         }
  222.  
  223.     if (nbad) {    /* there are bad sectors found not added to BSL yet */
  224.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  225.         ret = ERROR;
  226.         goto badnews; 
  227.         }
  228.         totbad += ret;    /* increment num bad sectors existing */
  229.         prnbad(totbad);
  230.     }
  231.     
  232.         /*-----------------------------------------------------------*/
  233.         /* Read lots of sectors (one cylinder worth) at a time.      */
  234.         /* If read error, loop through sectors within that cylinder  */
  235.         /* to find out exactly which sector(s) is bad, and add it to */
  236.         /* the bad sector list if it's not already there.         */
  237.         /*                                 */
  238.         /* Data read is compared to data written.  If there is any   */
  239.         /* discrepancy within a sector, mark that sector as bad in   */
  240.         /* the bad sector list.                         */
  241.         /*-----------------------------------------------------------*/
  242.  
  243.         nbad = 0;    /* no bad sectors for this cylinder yet */
  244.         if ((ret = rdsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  245.             if (tsterr(ret) == OK) {
  246.                 ret = ERROR;
  247.                 goto badnews;
  248.             }
  249.             cnt = sectcnt;
  250.             where = start;
  251.             while (cnt) {
  252.                 if ((ret = rdsects(pdev, 1, databuf, where)) != 0) {
  253.                     if (tsterr(ret) == OK) {
  254.                     ret = ERROR;
  255.                     goto badnews;
  256.                     }
  257.                     if (where < 3) {
  258.                       ret = err(rsrvbad);
  259.                       goto badnews;
  260.                   }
  261.                      badbuf[nbad++] = where;    /* store bad sector num */
  262.                 } else {
  263.                     if (!blktst(databuf, pattern, 512L)) {
  264.                         if (where < 3) {
  265.                           ret = err(rsrvbad);
  266.                           goto badnews;
  267.                       }
  268.                         badbuf[nbad++] = where;    /* store bad sector num */
  269.                     }
  270.                 }
  271.         /* buffer is filled up, have to add bad sectors
  272.                    found so far to the BSL before continuing.   */
  273.                 if (nbad == WARNBADSECTS) {
  274.                     if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  275.                         ret = ERROR;
  276.                         goto badnews;
  277.                     }
  278.                     totbad += ret;    /* incr num bad sectors existing */
  279.                     prnbad(totbad);
  280.                     nbad = 0;    /* start counting again */
  281.                 }
  282.                 where++;
  283.                 cnt--;
  284.             }
  285.             clean = 0;
  286.         } else {
  287.             clean = 1;
  288.         }
  289.         
  290.         if (nbad) { /* there are bad sectors found not added to BSL yet */
  291.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  292.                 ret = ERROR;
  293.                 goto badnews;
  294.             }
  295.             totbad += ret;    /* incr num bad sectors added to BSL */
  296.             prnbad(totbad);
  297.         } else if (clean) {
  298.         /* compare data read with data written, record bad sectors if any */
  299.             if ((ret = cmpdata(pdev, start, databuf, (int)sectcnt, pattern))
  300.                  < 0) {
  301.                 ret = ERROR;
  302.                 goto badnews;
  303.             } else {
  304.                 totbad += ret;    /* incr num bad sectors added to BSL */
  305.                 prnbad(totbad);
  306.             }
  307.         }
  308.         start += sectcnt;
  309.         sect2mark -= sectcnt;
  310.         
  311.         /* update bar on screen */
  312.         dmrkmsg[DMRKBAR].ob_width
  313.             = (dmrkmsg[DMRKBOX].ob_width * (hdsiz - sect2mark)) / hdsiz;
  314.     objc_draw(dmrkmsg, DMRKBAR, MAX_DEPTH, 0, 0, wdesk, hdesk);
  315.     }
  316. badnews:
  317.     if (ret < 0)        /* if an error occurs,            */
  318.         return(ret);        /*    return the error            */
  319.     else return(totbad);    /* else return number of bad sectors found. */
  320. }
  321.  
  322.  
  323. /*
  324.  *  Update number of bad sectors found during Destructive Markbad in
  325.  *  the dialogue box.
  326.  *    Input:
  327.  *        totbad - number of bad sectors found so far.
  328.  */
  329. prnbad(totbad)
  330. long totbad;
  331. {
  332.     char numbuf[10];
  333.     
  334.     ltoa(totbad, numbuf);
  335.     (dmrkmsg[NEWBAD].ob_spec)->te_ptext = numbuf;
  336.     objc_draw(dmrkmsg, NEWBAD, MAX_DEPTH, 0, 0, wdesk, hdesk);
  337. }
  338.  
  339. /*
  340.  *  Compare data read with data written of a cylinder, and mark sectors
  341.  *  with data error in the bad sector list.
  342.  *    Input:
  343.  *        pdev - physical unit BSL belongs to.
  344.  *        start - starting physical sector number of the cylinder.
  345.  *        databuf - data read from the cylinder.
  346.  *        numsect - number of sectors to be compared.
  347.  *        pattern - long pattern written on the cylinder.
  348.  *    Output:
  349.  *        bsl - an updated bad sector list with the newly found bad
  350.  *              sectors marked in it.
  351.  */
  352. cmpdata(pdev, start, readbuf, numsect, pattern)
  353. int pdev;    /* physical device number */
  354. SECTOR start;    /* phys sect num of where cylinder starts */
  355. BYTE *readbuf;    /* data read */
  356. int numsect;    /* num sectors to be compared */
  357. long pattern;    /* correct data pattern */
  358. {
  359.     int i, cnt;            /* indices into databuf, counter */
  360.     int nbad;            /* num bad sectors found so far */
  361.     int totbad;            /* total num bad sectors found in cylinder */
  362.     int ret;            /* return code from addbsl() */
  363.     
  364.     totbad = nbad = 0;    /* no bad sectors found yet */
  365.     
  366.     /* Test whole chunk first, if OK, ship it.  
  367.        Return 0 for no bad sectors found. */
  368.     if (blktst(readbuf, pattern, (long)numsect*512))
  369.         return 0;
  370.         
  371.     for (cnt = 0; cnt < numsect; cnt++) {
  372.         if (!blktst(readbuf, pattern, 512L)) {
  373.         badbuf[nbad++] = start + cnt;    /* store bad sector num */
  374.     }
  375.     readbuf += 512L;
  376.         if (nbad == WARNBADSECTS) {
  377.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  378.                 return ret;
  379.             }
  380.             totbad += ret;    /* incr num bad sectors added to BSL */
  381.             nbad = 0;        /* reinit counter for bad sectors to 0 */
  382.         }
  383.     }
  384.     if (nbad) {    /* bad sectors found but not added to BSL yet */
  385.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  386.             return ret;
  387.         }
  388.         totbad += ret;    /* incr num bad sectors added to BSL */
  389.     }
  390.     return(totbad);
  391. }
  392.